#include "Animation.h"

#include "..\..\SGD Wrappers\SGD_Handle.h"
#include "..\..\SGD Wrappers\SGD_GraphicsManager.h"

Animation::Animation(bool loop)
{
	SetScale(1.0f);
	SetCurrentFrame(0);
	bIsLooping = loop;
	bIsPlaying = true;
}

Animation::Animation(const Animation& copy)
{
	SetScale(1.0f);
	pImage = copy.pImage;
	bIsLooping = copy.bIsLooping;
	bIsPlaying = copy.bIsPlaying;
	iCurFrame = copy.iCurFrame;
	for (unsigned int i = 0; i < copy.vFrames.size(); ++i)
	{
		vFrames.push_back(Frame(copy.vFrames[i]));
	}
}

Animation::~Animation()
{
	if (vFrames.size() > 0)
	{
		vFrames.clear();
	}
}

// Accessors
SGD::HTexture& Animation::GetImage()
{
	return pImage;
}

Frame& Animation::GetFrame()
{
	return vFrames[iCurFrame];
}

int Animation::GetCurrentFrame()
{
	return iCurFrame;
}

SGD::Rectangle Animation::GetCollisionRect(SGD::Point position)
{
	return GetFrame().GetCollisionRect(position);
}

SGD::Rectangle Animation::GetDrawRect()
{
	return GetFrame().GetDrawRect();
}

bool Animation::IsLooping()
{
	return bIsLooping;
}

bool Animation::IsPlaying()
{
	return bIsPlaying;
}

float Animation::GetRightCollision()
{
	return GetFrame().GetCollisionRight();
}

float Animation::GetTopCollision()
{
	return GetFrame().GetCollisionTop();
}

float Animation::GetLeftCollision()
{
	return GetFrame().GetCollisionLeft();
}

float Animation::GetScale()
{
	return fScale;
}

// Mutators
void Animation::SetImage(SGD::HTexture image)
{
	pImage = image;
}

void Animation::AddFrame(Frame frame)
{
	vFrames.push_back(frame);
}

void Animation::SetCurrentFrame(int frame)
{
	iCurFrame = frame;
}

void Animation::IsLooping(bool loop)
{
	bIsLooping = loop;
}

void Animation::IsPlaying(bool play)
{
	bIsPlaying = play;
}

void Animation::Update(float dt)
{

	if (vFrames.size() == 0)
		return;

	if (IsPlaying())
	{
		// Increment Timer
		vFrames[iCurFrame].SetCurrentTime(vFrames[iCurFrame].GetCurrentTime() + dt);

		// Run Next Frame
		if (vFrames[iCurFrame].GetCurrentTime() >= vFrames[iCurFrame].GetMaxTime())
		{
			vFrames[iCurFrame].SetCurrentTime(0.0f);
			++iCurFrame;

			// Check if last frame
			if (iCurFrame == vFrames.size())
			{
				// Is animation looping
				if (!IsLooping())
				{
					--iCurFrame;
					IsPlaying(false);
				}
				else
					SetCurrentFrame(0);
			}
		}
	}
}

void Animation::Render(SGD::Point position)
{
	// Draw nothing if there are no frames
	if (vFrames.empty() || GetImage() == SGD::INVALID_HANDLE)
		return;

	// Retrieve the source rect for the current frame
	SGD::Rectangle sourceRect = vFrames[iCurFrame].GetDrawRect();
	SGD::Point drawPoint = vFrames[iCurFrame].GetDestDrawPoint(position);

	SGD::Size scale = SGD::Size{ 1.0f * GetScale(), 1.0f  * GetScale() };
	if (vFrames[iCurFrame].IsFlipped())
	{
		scale.width *= -1.0f;
	}

	// Offset by frame's anchor-point
	SGD::GraphicsManager::GetInstance()->DrawTextureSection(GetImage(),
		drawPoint,
		sourceRect,
		0.0f, SGD::Vector{},
		SGD::Color{}, scale);
}

void Animation::Clear()
{
	if (vFrames.size() > 0)
		vFrames.clear();
	IsLooping(true);
}

void Animation::SetScale(float scale)
{
	fScale = scale;
}